Certificación en Ciencia de datos

Módulo 3 - Más ggplot2

Natalia da Silva

2024 -Módulo 3

Vimos

  • Visualizaciones básicas con ggplot2

  • Uso de scales para controlar los aes del gráfico

  • Fundamentos del uso de color

Recapitulando

Un gráfico estadístico es un mapeo de los datos a atributos estéticos (ejem: color, forma, tamaño) de objetos geométricos (ejem: puntos, lineas, barras)

VER QUE DECIR

Actividad 2

Vemos la solución de la Actividad2

Componentes de ejes y leyendas

theme

  • theme en un gráfico permite controlar los elementos que no son datos en el mismo.

  • Ayuda a hacer tu gráfico estéticamente como lo querés no afecta el mapeo de datos.

  • theme te da control sobre las fuente, el fondo, ticks, etc.

theme

El sistema de themes tiene 4 componentes:

  • Elementos de theme especifican todo lo que puedo cambiar que no son datos en un gráfico (ej: plot.title, axis.ticks.x)

  • Cada elemento se asocia una función de elementos que describe las propiedades visuales del elemento. Ejemplo element_text() fija el tamaño de la fuente.

  • La función theme() permite sobrescribr los elementos del theme por defecto mediante las funciones de los elementos ejemplo `theme(plot.title = element_text(colour = “red”))

  • Themas completos como theme_bw(), theme_grey() fija todos los elementos del tema con valores designados para funcionar armoniosamente.

elements para los ejes

Controla la aparicencia de los ejes

elements para los ejes

  • axis.text (axis.title) vienen en tres formas:axis.text, axis.text.x y axis.text.y.

  • Si querés modificar las propiedades de ambos ejes de una, hay que usar axis.text

Ejemplo propina

theme()

Si queremos cambiar el tamaño de la fuente del eje

library(readr)
propinas <- read_csv("propina.csv")
ggplot(data = propinas, aes(x = sexo, fill = sexo)) +
  geom_bar() + labs(x = "Sexo", y = "Cantidad", fill = "Sexo") +
                            theme(
  axis.text = element_text(size = 13, color ="grey"))

theme()

Si queremos cambiar el tamaño de la fuente del título

ggplot(data = propinas, aes(x = sexo, fill = sexo)) +
  geom_bar() + labs(x = "Sexo", y = "Cantidad", fill = "Sexo") + 
  theme(axis.title = element_text(size = 15))

Cambiar theme

ggplot(data = propinas, aes(x = sexo, fill = sexo)) +
  geom_bar() + labs(x = "Sexo", y = "Cantidad", fill = "Sexo") +
  theme( axis.title = element_text(size = 20), 
        axis.text.x = element_text(size =15, color = "grey"), 
        axis.text.y = element_text(size =15, color = 'grey'))

Cambiar theme

Diferencia con el anterior?

ggplot(data = propinas, aes(x = sexo, fill = sexo)) +
  geom_bar() + labs(x = "Sexo", y = "Cantidad", fill = "Sexo") +
  theme( axis.title.x = element_text(size = 20), 
        axis.text.x = element_text(size =15, color = "grey"), 
        axis.text.y = element_text(size =15, color = 'grey'))

elements para la leyenda

Cambiar theme

  • Posición de la leyenda
ggplot(data = propinas, aes(x = sexo, fill = sexo)) +
  geom_bar() + labs(x = "Sexo", y = "Cantidad", fill = "Sexo") +
  theme(legend.position = "top")

Cambiar theme

ggplot(data = propinas, aes(x = sexo, fill = sexo)) +
  geom_bar() + 
  labs(x = "Sexo", y = "Cantidad", fill = "Sexo") + theme(legend.position = "top",
        legend.title = element_text(size = 20,color = 'red'), 
        legend.text = element_text(size = 20,color='blue'))

Cambiar theme

ggplot(data = propinas, aes(x = sexo, fill = sexo)) +
  geom_bar() + labs(x = "Sexo", y = "Cantidad", fill = "Sexo")+ 
  theme(legend.key.size = unit(1, 'cm'), 
        legend.key.height = unit(2, 'cm'), 
        legend.key.width = unit(1, 'cm'))

elements para los paneles

elements para subplots, facets

theme()

ggplot(data = propinas, aes(x = sexo, fill = sexo)) +
  geom_bar() + labs(x = "Sexo", y = "Cantidad", fill = "Sexo") + 
  theme_bw()

themes predefinidos

Más

  • theme_dark()

  • theme_minimal()

  • theme_void()

  • theme_test()

theme()

theme()

ggplot(data = propinas, aes(x = sexo, fill = sexo)) +
  geom_bar() + labs(x = "Sexo", y = "Cantidad", fill = "Sexo")  + 
  theme(aspect.ratio = 1, legend.position = "bottom",
        panel.background = element_rect(fill = "white"),
        panel.border = element_rect(colour = "grey20", fill = NA),
        panel.grid = element_line(colour = "grey92"),
        panel.grid.minor = element_line(size=rel(0.5)),
        strip.background = element_rect(fill="grey85",
                                        colour="grey20"),
        legend.key = element_rect(fill="white"))

Transformaciones estadísticas

  • Transforma los datos, resumiendolos de alguna manera (stat)
  • Ya usamos muchos stats con ggplot2 pero está implícito y no los vemos

Por ejemplo:

  • geom_boxplot() usa stat_boxplot() y calcula los 5 resumenes estadísticos (min, max Q1, Q2, Q3 y media).

  • geom_bar() usa stat_count cuenta las observaciones en cada categoría

  • geom_histogram() usa stat_bin() que parte el eje x en trozos y cuenta la cantidad de observaciones en cada uno.

Gráficos de caja

pl1 <- ggplot(data =  propinas, aes(x = dia, y = total)) +
  geom_boxplot()

Mirar ?geom_boxplot

Gráficos de caja

pl1 <- ggplot(data =  propinas, aes(x = dia, y = total)) +
  geom_boxplot()

#Equivalente a:

pl1 <- ggplot(data =  propinas, aes(x = dia, y = total)) +
  stat_boxplot()

Gráficos de caja

  • stat_boxplot() calcula los 5 resumenes estadisticos y esos datos se usan para dibuar ¿Donde están los datos?

Miramos los datos que genera el gráfico

layer_data(pl1)
  ymin   lower middle   upper  ymax                          outliers
1 7.25 14.9875  19.63 25.5975 40.55                      48.17, 45.35
2 7.51 12.4425  16.20 20.1550 29.80 32.68, 34.83, 34.30, 41.19, 43.11
3 3.07 13.9050  18.24 24.7400 39.42        48.27, 44.30, 50.81, 48.33
4 5.75 12.0950  15.38 21.7500 28.97                             40.17
  notchupper notchlower x flipped_aes PANEL group ymin_final ymax_final  xmin
1   21.55294   17.70706 1       FALSE     1     1       7.25      48.17 0.625
2   17.74759   14.65241 2       FALSE     1     2       7.51      43.11 1.625
3   20.07538   16.40462 3       FALSE     1     3       3.07      50.81 2.625
4   18.87971   11.88029 4       FALSE     1     4       5.75      40.17 3.625
   xmax xid newx new_width weight colour  fill alpha shape linetype linewidth
1 1.375   1    1      0.75      1 grey20 white    NA    19    solid       0.5
2 2.375   2    2      0.75      1 grey20 white    NA    19    solid       0.5
3 3.375   3    3      0.75      1 grey20 white    NA    19    solid       0.5
4 4.375   4    4      0.75      1 grey20 white    NA    19    solid       0.5

Gráficos de barras

 ggplot(data = propinas, aes(x = dia)) +
   geom_bar() +
  labs(x = "Días de la semana", y = "Total de mesas servidas")

Gráficos de barras

  • En el eje x nos nuestra los días de la semana.

  • En el eje y nos muestra el conteo, total de mesas servidas.

  • Pero si miramos los datos no tenemos ninguna variable que sea el conteo head(propinas).

  • Muchos gráficos usan los datos originales pero otros calculan nuevos valores para hacer el plot.

  • stat_count() cuenta el número de puntos que caen en cada bin.

Gráficos de barras

pl_bar <- ggplot(data = propinas, aes(x = dia)) +
   geom_bar() +
  labs(x = "Días de la semana", y = "Total de mesas servidas")

layer_data(pl_bar)
   y count prop x flipped_aes PANEL group ymin ymax xmin xmax colour   fill
1 76    76    1 1       FALSE     1     1    0   76 0.55 1.45     NA grey35
2 62    62    1 2       FALSE     1     2    0   62 1.55 2.45     NA grey35
3 87    87    1 3       FALSE     1     3    0   87 2.55 3.45     NA grey35
4 19    19    1 4       FALSE     1     4    0   19 3.55 4.45     NA grey35
  linewidth linetype alpha
1       0.5        1    NA
2       0.5        1    NA
3       0.5        1    NA
4       0.5        1    NA

Gráficos de barras

  • geom_bar() usa los datos transformados para construir el plot

  • x son los días y en y pone el conteo que calcula internamente.

  • el argumento por defecto de stat en geom_bar() es count

Gráficos de barras

  • stat y geom intercambiables
#Mirar ?geom_bar

pl_bar <- ggplot(data = propinas, aes(x = dia)) +
   geom_bar() +
  labs(x = "Días de la semana", y = "Total de mesas servidas")


#Equivalente a: 
 
pl_bar <- ggplot(data = propinas, aes(x = dia)) +
   stat_count() +
  labs(x = "Días de la semana", y = "Total de mesas servidas")

Gráficos de barras

  • Imaginate que los datos que tengo son el porcentaje de personas en cada día

  • Quiero directamente graficar el porcentaje de personas por día.

dt <- data.frame(dia = c("Do", "Ju", "Sa", "Vi"),
                 perc = c(21, 25, 36, 8))

dt
  dia perc
1  Do   21
2  Ju   25
3  Sa   36
4  Vi    8

Gráficos de barras

pl_dt <- ggplot(data = dt, aes(x = dia, y = perc)) +
  geom_bar(stat = "identity")

layer_data(pl_dt)
  x  y PANEL group flipped_aes ymin ymax xmin xmax colour   fill linewidth
1 1 21     1     1       FALSE    0   21 0.55 1.45     NA grey35       0.5
2 2 25     1     2       FALSE    0   25 1.55 2.45     NA grey35       0.5
3 3 36     1     3       FALSE    0   36 2.55 3.45     NA grey35       0.5
4 4  8     1     4       FALSE    0    8 3.55 4.45     NA grey35       0.5
  linetype alpha
1        1    NA
2        1    NA
3        1    NA
4        1    NA

Gráficos de barras

Puedo alternativamente hacer la transformación en y

pl_perc<- ggplot(data = propinas, aes(x = dia, 
                                      y = after_stat(count/sum(count)))) +
  geom_bar() + scale_y_continuous(labels = percent) +
  labs(y = "Porcentaje")

Gráficos de barras

Puedo alternativamente hacer la transformación en y

layer_data(pl_perc)
           y count prop x flipped_aes PANEL group ymin       ymax xmin xmax
1 0.31147541    76    1 1       FALSE     1     1    0 0.31147541 0.55 1.45
2 0.25409836    62    1 2       FALSE     1     2    0 0.25409836 1.55 2.45
3 0.35655738    87    1 3       FALSE     1     3    0 0.35655738 2.55 3.45
4 0.07786885    19    1 4       FALSE     1     4    0 0.07786885 3.55 4.45
  colour   fill linewidth linetype alpha
1     NA grey35       0.5        1    NA
2     NA grey35       0.5        1    NA
3     NA grey35       0.5        1    NA
4     NA grey35       0.5        1    NA

Gráficos de barras

También me puede interesar saber el promedio del la cuenta total en cada día

ggplot(data = propinas, aes(x = dia, y = total)) +
  geom_bar(stat ='summary_bin', fun = mean) +
  labs(y = "Gasto promedio en USD")

Más viz

  • Los datos comunmente tienen más de dos variables por lo que puede ser más complicado de graficar.

  • Con muchas variables, especialmente si hay alguna asociación entre ellas, podríamos llamarlos multivariados o de altas dimenisiones.

  • Cuando las variable son todas cuantitativas la visualización en altas dimensiones recae en algún tipo de reducción de dimensiones (PCA, LDA, projection pursuit, MDS,etc).

Ejemplo: Lending Club

Lending Club: plataforma peer-to-peer para pedir plata de un prestamista para casi cualquier propósito, alternativo al sistema financiero. Se puede pedir hasta $40,000 y los inversores invertir desde $25. Cada usuario paga un precio por el servicio de la plataforma.

Usaremos datos de Indiana.

Data available in: indiana link

Leer los datos

library(here)
library(tidyverse)
library(GGally)
indiana <- read_csv(here('indiana_data.csv'))

str(indiana)
spc_tbl_ [443 × 15] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ loan_amnt            : num [1:443] 1000 25000 22550 2975 11300 ...
 $ term                 : chr [1:443] "36 months" "36 months" "36 months" "36 months" ...
 $ int_rate             : num [1:443] 9.64 9.64 15.96 9.96 12.17 ...
 $ emp_length           : num [1:443] 0 2 4 0 8 8 2 4 7 2 ...
 $ home_ownership       : chr [1:443] "RENT" "RENT" "MORTGAGE" "RENT" ...
 $ annual_inc           : num [1:443] 5000 48000 34992 25000 33600 ...
 $ purpose              : chr [1:443] "debt_consolidation" "debt_consolidation" "debt_consolidation" "debt_consolidation" ...
 $ addr_state           : chr [1:443] "IN" "IN" "IN" "IN" ...
 $ dti                  : num [1:443] 18 9.78 20.82 14.16 23.96 ...
 $ delinq_2yrs          : num [1:443] 0 0 1 0 0 0 0 0 0 0 ...
 $ revol_util           : num [1:443] 26 12.7 48.9 33.7 49 0 70.9 23.9 14.4 53.3 ...
 $ total_acc            : num [1:443] 7 39 22 9 15 9 6 22 29 15 ...
 $ bad_loan             : chr [1:443] "good" "good" "good" "good" ...
 $ longest_credit_length: num [1:443] 3 7 18 5 8 9 7 12 15 4 ...
 $ verification_status  : chr [1:443] "not verified" "not verified" "not verified" "not verified" ...
 - attr(*, "spec")=
  .. cols(
  ..   loan_amnt = col_double(),
  ..   term = col_character(),
  ..   int_rate = col_double(),
  ..   emp_length = col_double(),
  ..   home_ownership = col_character(),
  ..   annual_inc = col_double(),
  ..   purpose = col_character(),
  ..   addr_state = col_character(),
  ..   dti = col_double(),
  ..   delinq_2yrs = col_double(),
  ..   revol_util = col_double(),
  ..   total_acc = col_double(),
  ..   bad_loan = col_character(),
  ..   longest_credit_length = col_double(),
  ..   verification_status = col_character()
  .. )
 - attr(*, "problems")=<externalptr> 

Data

Variable Description
loan_amnt Monto del préstamo
term Plazo (36, 60 meses)
int_rate Tasa de interés
emp_length Años de trabajo
home_ownership Propietario de la casa
annual_inc Ingreso anual
purpose Propósito del crédito
addr_state Estado dirección
dti Deuda/ingreso mensual
delinq_2yrs Antecedentes criminales en los últimos 2 años
revol_util Proporción de la linea de crédito utilizada
total_acc Totalde lineas de crédito
bad_loan Indica si el crédito no fue pagado
longest_credit_length Años de la linea de crédito más larga
verification_status Ingreso verificado

Mosaic plots

Mosaic plots:

  • Método gáfico para visualizar datos de dos o más variables cualitativas.

  • Es el análogo gráfico de las tablas multivariadas de contingencia.

  • Da una visión general de los datos y permite reconocer relaciones entre diferentes variables.

  • Por ejemplo, la independencia se muestra cuando las cajas para todas las categorías tienen la misma área.

  • Las variables categóricas se ponen en orden y luego cada variable se asigna a un eje.

  • Se puede interpretar en término de distribución conjunta descompuesta como condicional por marginal.

Mosaic plots

  • Usaremos el paquete ggmosaic diseñado en el marco de ggplot2

  • Uno puede crear en el aes la formula que determina como se particiona la distribución conjunta.

  • Para acomodar varias variables el mapeo de x debe ser definido con product() Ejemplo V1 y and V2 se leen comox = product(V2, V1).

  • La conjunta entendida como producto de la distribución condicional y la marginal.

  • El orden en que se ponen las variables es importante.

  • https://cran.r-project.org/web/packages/ggmosaic/vignettes/ggmosaic.html

Mosaic plots

¿Qué pueden decirme sobre este gráfico? ::: {.cell}

library(ggmosaic)
ggplot(data = indiana) +
  geom_mosaic(aes(x = product(bad_loan, term), fill= bad_loan)) +
  labs(title='f(bad_loan | term) f(term)')

:::

Mosaic plots

library(ggmosaic)
ggplot(data = indiana) +
  geom_mosaic(aes(x = product( term, bad_loan,), fill= term)) +
  labs(title='f(term | bad_loan) f(bad_loan)')

Alluvial plot

Exploren esto para variables categóricas

https://cran.r-project.org/web/packages/ggalluvial/vignettes/ggalluvial.html

Múltiples dimensiones

Scatterplot matrix es un gráfico básico para datos multivariados.

Ejemplo Lending club ::: {.cell}

ggscatmat(indiana, columns = c(1,3,6,9,11,12),alpha = 1/5)

:::

Múltiples dimensiones

Scatterplot matrix, ejemplo de lending club coloreado por bad_loan

ggscatmat(indiana, columns = c(1,3,6,9,11,12),
          color = "bad_loan", alpha = 1/3)

Múltiples dimensiones

Scatterplot matrix es un gráfico básico para datos multivariados

  • Se puede hacer usando el paquete GGally

  • ggscatmat estrictamente usa variables numéricas

  • https://ggobi.github.io/ggally/reference/ggpairs.html

Múltiples dimensiones

Para distinto tipo de variables podemos usar la función ggpairs() de GGally

  ggpairs(indiana, columns = c(1,2,5,6,9,13) )

Parallel coordinate plot

  • PCP útil para visualizar datos multivariados numéricos.

  • Permite comparar muchas variables conjuntamente y ver la relación entre ellas, identificar y caracterizar observaciones.

  • fortaleza es que las variables pueden ser totalmente distintas: diferentes rangos y diferentes unidades.

  • Para visualizarlas juntas necesitamos normalizarlas.

### Parallel coordinate plot
- Cada variable está representada por un eje separado (línea vertical). Todos los ejes están igualmente espaciados y paralelos entre sí.
- Cada eje puede tener una escala diferente, ya que cada variable trabaja con una unidad de medida diferente, o se pueden normalizar todos los ejes para mantener todas las escalas uniformes.
- Cada observación se traza horizontalmente como una serie de líneas que conectan todas las variables.
- Las características se pueden ordenar para que no haya demasiadas líneas que se crucen, lo que resulta en un gráfico ilegible.
- Con la visualización interactiva, puede resaltar una o más líneas para centrarse en una parte de la trama que interese.

Example: Parallel cordinate plot

  • Una desventaja de los diagramas de coordenadas paralelas es que pueden abarrotarse demasiado y, por lo tanto, ser ilegibles cuando son muy densos en datos.

  • La interactividad puede ayudar a superar el problema, puedes resalte una línea o un grupo de líneas y esto le permite aislar secciones de la trama que le interesan mientras filtra el ruido.

Example: Parallel cordinate plot

ggparcoord(data = indiana, columns = c(1,3,4,6,9:12), alpha=1/4)

Example: Parallel cordinate plot

ggparcoord(data = indiana, columns = c(1,3,4,6,9:12), groupColumn =2,
           alpha = 1/6)

Example: Parallel cordinate plot

ggparcoord( data= indiana, columns = c(1,3,4,6,9:12),
            groupColumn =2, alpha=1/6)

Multidimensional scaling

  • Multidimensional scaling (MDS) se usa para reducir dimensiones para ver similaridades entre observaciones.

  • MDS transforma los datos en un espacio de menores dimensiones, toma un conjunto de similaridades y retorna un conjunto de puntos tal que la distancia entre los puntos es aproximadamente igual a las similaridades en el espacio completo.

Herramientas para visualizar datos en altas dimensiones

  • Visualización interactiva.

  • Linked brushing, permite mirar diferentes secciones de los datos.

  • Grand tour, es útil para mirar muchas proyecciones de los datos.

Gráficos interactivos

Hemos visto hasta ahora como hacer gráficos estáticos con ggplot2

  • Los gráficos interactivos permiten obtener información adicional, pintar partes del gráfio entre otros

  • A su vez son interactivos aquellos gráficos que permiten links entre ellos

  • Hay otros paquetes que sirven para hacer gráficos interactivos como plotly, htmlwidgets, ggvis, shiny

Para que interactivos

Pueden ser necesarios para:

  • Identificar estructuras que de otra forma se perderían

  • Diagnosticar modelos y entender algoritmos

  • Permite buscar información rápida sin especificar completamente las preguntas

Gráficos interactivos con plotly

plotly permite hacer visualizaciones interactivas, realizado por Carson Sievert.

https://plotly-r.com

  • Tiene una función que permite la traducción directa de gáficos estáticos de ggplot2 a interactivos
library(shiny)
library(tidyverse)
library(here)

pl1<- propinas %>%
ggplot(aes(y = total,  x = propina )) +
      geom_point() + theme(aspect.ratio = 1)

Gráficos interactivos con plotly

ggplot2a interactivo con plotly

library(plotly)
ggplotly(pl1)

ggplot2a interactivo con plotly

  • ggplotly() tiene el argumento tooltip que por defecto es "all"

  • Significa que en la etiqueta que se muestra está la información de todos los aes

ggplot2 y plotly

ggplot2a interactivo con plotly

library(plotly)
hi <- highlight_key(propinas)
pl2 <- ggplot(hi, aes(y = total,  x = propina )) + geom_point()
hi2 <- highlight(p = ggplotly(pl2), on = "plotly_selected")
crosstalk::bscols(hi2, DT::datatable(hi))

plotly en shiny

  • Se pueden poner gráficos interactivos basados en plotly en shiny

  • Están las funciones plotlyOutput y renderPlotlyque son similares a plotOutput y renderPlot

  • Más capítulo 17 del libro de plotly

Visualización interactiva con shiny

  • plotOutput permite hacer visualización interactiva
  • Hay 4 interactividades básicas que se pueden realizar con el mouse (click, dblClick, hovery brush) ::: {.cell}
?plotOutput

::: - de la misma forma que outputId genera un objeto de tipo input el argumento click, dblClick, hover y brush generan inputs,

  • plotOutput(outputId = "plot1", click = "click_plot1") crea input$clock_plot1 que guarda la info del click

Visualización interactiva con shiny

ui <- fluidPage(
  plotOutput("plot1", brush = "plot1_brush"),
   DTOutput("data")
)

server <- function(input, output) {
  output$plot1 <- renderPlot({
    propinas %>%
ggplot(aes(y = total,  x = propina )) +
      geom_point() +
  theme(aspect.ratio = 1)
  })

output$data <- renderDT({
    brushedPoints(propinas, input$plot1_brush)
  })
}

shinyApp(ui, server)

Tu turno

Material del curso

Material del curso está bajo licencia Creative Commons BY-NC-SA 3.0